<template>
  <div :id="`wft-advanced-form-${curComp.id}`" @dblclick.stop="advancedFormDblclick" @mousedown="deactivatedFormItem" @contextmenu="advancedFormContextHandler" :class="['wft-advanced-form', { 'wft-loop-glowing': curComp.config.isEnchase }]">
    <el-form :label-width="`${attrs.labelWidth}px`" :label-align="attrs.labelAlign">
      <VueDraggable :animation="200" v-model="curComp.children">
        <div v-for="(comp, index) in curComp.children" :key="comp.id" :class="['form-item', { activeItem: comp.config.isActive }]" :style="{ 'pointer-events': curComp.config.isEnchase ? 'auto' : 'none' }" @mousedown.stop="formItemClick(comp)">
          <el-form-item :label="`${getAttrs(comp.attrs).label}：`" :label-width="`${getAttrs(comp.attrs).labelWidth}px`":rules="[{ required: getAttrs(comp.attrs).required, message: '', trigger: 'blur' }]">
            <component :is="`${comp.key}Temp`" :cur-comp="comp" :panel-json="panelJson" />
          </el-form-item>
          <i class="wft-icon-delete" @mousedown.stop @click.stop="delFormItem(comp, index)" />
        </div>
      </VueDraggable>
    </el-form>
    <!-- 画板右键 -->
    <AdvancedFormContextPanel
      v-if="showAdvancedFormPanelContext"
      v-bind="contextConfig"
      :curComp="curComp"
      :id="`wft-advanced-form-${curComp.id}`"
    />
    <!-- 文字提示 -->
    <div class="advanced-form-tip" v-show="!curComp.config.isEnchase && !curComp.children!.length">
      <p>双击切换状态</p>
    </div>
  </div>
</template>
<script setup lang="ts">
import { getUuid } from 'wft-utils'
import Bus from '@/utils/bus'
import AdvancedFormContextPanel from './context.vue'
import { VueDraggable } from 'vue-draggable-plus'
import { useAttrs } from 'generator/hooks'
import { onMounted, onUnmounted, ref } from 'vue'
import { useMessage } from '@/hooks'
import { DragEventEnum, DragKeyEnum } from '@/enums';
import { getAttrs } from 'generator/utils'

const props = defineProps<{
  panelJson: TPanel
  curComp: TComp
}>()

const attrs = useAttrs(props.curComp.attrs)

const contextConfig = ref<{
  top: number | string,
  left: number | string,
  right: string | number,
  bottom: string| number
}>({
  top: 0,
  left: 0,
  right: 'none',
  bottom: 'none'
})
const showAdvancedFormPanelContext = ref(false)

const emits = defineEmits<{
  (e: 'onActivated', curComp: TComp): void;
  (e: 'compContext', ...args: any[]): void;
}>()

onMounted(() => {
  Bus.on('hideAdvancedFormPanelContext', hideAdvancedFormPanelContext)
})
onUnmounted(() => {
  Bus.off('hideAdvancedFormPanelContext', hideAdvancedFormPanelContext)
})

// 表单控件点击
function formItemClick(comp: TComp) {
  props.curComp.children!.forEach(item => item.config.isActive = false)
  comp.config.isActive = true
  emits('onActivated', comp)
}

// 删除表单控件
function delFormItem(comp: TComp, index: number) {
  const isActive = comp.config.isActive
  props.curComp.children?.splice(index, 1)
  if(!isActive || !props.curComp.children?.length) return
  if(index == props.curComp.children?.length) {
    let activeComp = props.curComp.children?.[index - 1]
    activeComp.config.isActive = true
    emits('onActivated', activeComp)
  } else {
    let activeComp = props.curComp.children?.[index]
    activeComp.config.isActive = true
    emits('onActivated', activeComp)
  }
}

// 表单控件失活
function deactivatedFormItem() {
  props.curComp.children!.forEach(item => item.config.isActive = false)
}

// 容器右键
function advancedFormContextHandler(event: MouseEvent) {
  if(props.curComp.config.isEnchase) {
    event.stopPropagation()
    event.preventDefault()
    hideAdvancedFormPanelContext()
    initContextPosition(event)
    showAdvancedFormPanelContext.value = true
  }
}

// 隐藏右键面板
function hideAdvancedFormPanelContext() {
  showAdvancedFormPanelContext.value = false
}

// 初始化右键面板位置
function initContextPosition(event: MouseEvent) {
  const { left, top } = document.getElementById(`wft-advanced-form-${props.curComp.id}`)!.getBoundingClientRect()
  contextConfig.value.top = event.clientY - top
  contextConfig.value.left = event.clientX - left
  contextConfig.value.right = 'none'
  contextConfig.value.bottom = 'none'
}

// 双击可以拖动进来
function advancedFormDblclick() {
  props.curComp.config.isEnchase = !props.curComp.config.isEnchase
  props.curComp.config.draggable = !props.curComp.config.isEnchase
  props.curComp.config.resizable = !props.curComp.config.isEnchase
  if(props.curComp.config.isEnchase) {
    startEvent()
  } else {
    clearEvent()
  }
}

// 监听事件
function startEvent() {
  const advancedForm = document.getElementById(`wft-advanced-form-${props.curComp.id}`)!
  advancedForm.addEventListener(DragEventEnum.ON_DRAG_OVER, compDragover)
  advancedForm.addEventListener(DragEventEnum.ON_DROP, compDrop)
}

// 清除事件
function clearEvent() {
  const advancedForm = document.getElementById(`wft-advanced-form-${props.curComp.id}`)!
  advancedForm.removeEventListener(DragEventEnum.ON_DRAG_OVER, compDragover)
  advancedForm.removeEventListener(DragEventEnum.ON_DROP, compDrop)
}

function compDragover(e: DragEvent) {
  e.preventDefault()
}

// 松开拖拽组件
function compDrop(event: DragEvent) {
  if(!event.dataTransfer?.getData(DragKeyEnum.DRAG_DATA_KEY)) return
  const dragData = JSON.parse(event.dataTransfer.getData(DragKeyEnum.DRAG_DATA_KEY))
  if(dragData.curCom.type !== 'form') {
    return useMessage().warning('表单容器只能嵌套表单组件！')
  }
  const curCom = JSON.parse(JSON.stringify(dragData.curCom)) as TComp
  curCom.id = getUuid()
  curCom.config.isActive = true
  curCom.parentId = props.curComp.id
  curCom.parentKey = props.curComp.key
  props.curComp.children?.forEach(item => item.config.isActive = false)
  props.curComp.children?.push(curCom)
  emits('onActivated', curCom)
  Bus.emit('addStack')
  Bus.emit('startEventKeydown')
  if(event.dataTransfer?.getData(DragKeyEnum.DRAG_DATA_KEY)) {
    event.dataTransfer.clearData(DragKeyEnum.DRAG_DATA_KEY)
  }
}
</script>
<style scoped>
.wft-advanced-form {
  width: 100%;
  height: 100%;
  padding: 2px;
  box-sizing: border-box;
  overflow: hidden;
}

.advanced-form-tip {
  width: 100%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 14px;
  color: #999;
  text-align: center
}

.advanced-form-tip p {
  margin-top: 3px;
}

.wft-loop-glowing {
  box-shadow: 0 0 0 #d3e3fd, 0 0 10px #d3e3fd, 0 0 10px #d3e3fd, 0 0 30px #d3e3fd;
  cursor: auto;
}

.form-item {
  width: 100%;
  height: 40px;
  border: 1px dashed #e2e0e0;
  margin-bottom: 3px;
  cursor: move;
  box-sizing: border-box;
  position: relative;
  transition: border-color .3s;
  padding-top: 3px;
  box-sizing: border-box;
}

.form-item:hover {
  border-color: #03a9f4;
}

.form-item:hover .wft-icon-delete {
  opacity: 1;
}

.form-item .wft-icon-delete {
  position: absolute;
  font-size: 15px;
  color: #086d6d;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  opacity: 0;
  transition: opacity .3s;
  border: 1px solid #086d6d;
  border-radius: 50%;
  padding: 3px;
  cursor: pointer;
  z-index: 999;
}

.activeItem {
  border: 1px solid #03a9f4;
}
</style>
